package org.epanetgrid.otimizacao.objfunctions;

import java.util.HashSet;
import java.util.Set;

import javax.quantities.Length;
import javax.quantities.Pressure;
import javax.quantities.Velocity;

import org.epanetgrid.resultado.ResultadoSimulacao;
import org.epanetgrid.resultado.output.IAlarme;

/**
 * Classe que retorna a severidade do primeiro alarme
 *
 * @author alan
 */
public class SeveridadeObjectiveFunction implements ObjectiveFunction<ResultadoSimulacao, Integer> {

	private static final long serialVersionUID = -1136684216901180441L;

	/**
	 * @param resultado Resultado da simula��o a ser analisado.
	 * @return Severidade do primeiro alarme que ocorre. Desconsidera o primeiro alarme, pois � da malha
	 * que foi editada pelo usu�rio.
	 */
	public Integer evaluate(ResultadoSimulacao resultado) {
		if (resultado.getAlarmes().size() == 0) {
			return -1;
		}
		int worse = -1;
		
		Set<IAlarme> alarmes = new HashSet<IAlarme>();
		for (Set<IAlarme> alarmesIntervalo : resultado.getAlarmes()) {
			if ( !alarmesIntervalo.isEmpty() ) {
				alarmes.addAll(alarmesIntervalo);
				break;
			}
		}
		
		for (IAlarme alarme : alarmes) {
			int tmp = getSeveridade(alarme);
			if (worse < tmp) {
				worse = tmp;
			}
		}
		return new Integer(worse);
	}

	/**
	 * @param alarme
	 * @return Inteiro relativo a severidade do alarme
	 */
	private int getSeveridade(IAlarme alarme) {
		if(alarme.getTipoDeRestricao().equals(IAlarme.Tipo.warning) || 
				alarme.getTipoDeRestricao().equals(IAlarme.Tipo.unbalanced)) {
			return 2;
		}
		if (alarme.getTipoDeAlarme().equals(Pressure.SI_UNIT.getDimension())) {
			if (alarme.getTipoDeRestricao() == IAlarme.Tipo.max) {
				return 1;
			} else {
				return 1;
			}
		}
		if (alarme.getTipoDeAlarme().equals(Velocity.SI_UNIT.getDimension())) {
			if (alarme.getTipoDeRestricao() == IAlarme.Tipo.max) {
				return 0;
			} else {
				return 0;
			}
		}
		if (alarme.getTipoDeAlarme().equals(Length.SI_UNIT.getDimension())) {
			if (alarme.getTipoDeRestricao() == IAlarme.Tipo.max) {
				return 0;
			} else {
				return 1;
			}
		}
		return -1;
	}

}
